package com.sdy.resdir.biz.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.common.model.BizException;
import com.sdy.common.model.PageQuery;
import com.sdy.common.model.PageResult;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.StringUtil;
import com.sdy.resdir.biz.model.RdResManagement;
import com.sdy.resdir.biz.mapper.RdResManagementMapper;
import com.sdy.resdir.biz.model.RdResourceApplicationDetail;
import com.sdy.resdir.biz.model.RdResourceDir;
import com.sdy.resdir.biz.model.RdSystemIp;
import com.sdy.resdir.biz.service.RdResManagementService;
import com.sdy.mvc.service.impl.BaseServiceImpl;
import com.sdy.resdir.biz.service.RdResourceApplicationDetailService;
import com.sdy.resdir.biz.service.RdResourceDirService;
import com.sdy.resdir.biz.service.RdSystemIpService;
import com.sdy.resdir.biz.vo.UserResListVo;
import com.sdy.usercenter.api.UserQueryApi;
import com.sdy.usercenter.api.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 资源管理,关联用户所拥有资源 服务实现类
 * </p>
 *
 * @author hyh
 * @since 2019-10-29
 */
@Slf4j
@Service
public class RdResManagementServiceImpl extends BaseServiceImpl<RdResManagement> implements RdResManagementService {
    @Resource
    private RdResManagementMapper rdResManagementMapper;
    @Autowired
    private RdSystemIpService systemIpService;
    @Autowired
    private RdResourceDirService rdResourceDirService;
    @Autowired
    private RdResourceApplicationDetailService resOrderService;
    @Autowired
    private UserQueryApi userQueryApi;

    @Override
    public List<UserResListVo> getUserBindResList(Integer userId, Integer ipId, Page page) {
        List<UserResListVo> userResListVos = new ArrayList<>();
        List<String> resIdList = new ArrayList<>();
        if (null != ipId) {
            RdSystemIp ip = systemIpService.getOne(Wrappers.<RdSystemIp>lambdaQuery().eq(RdSystemIp::getId, ipId));
            if (StringUtil.isNotEmpty(ip.getResIdList()) && StringUtil.isNotBlank(ip.getResIdList())) {
                resIdList = Arrays.asList(ip.getResIdList().split(","));
                // 获取用户该IP已经关联的资源列表,通过查询该IP绑定的资源id
                List<RdResourceDir> getResList = rdResourceDirService.list(Wrappers.<RdResourceDir>lambdaQuery()
                        .in(RdResourceDir::getId, resIdList));
                for (RdResourceDir dir : getResList) {
                    userResListVos.add(new UserResListVo().setResId(dir.getId()).setResName(dir.getResName()).setState(1));
                }
            }
        }
        // 获取用户还未关联的资源列表,根据用户部门来查询
        UserDTO user = userQueryApi.getUser(userId);
        List<Integer> rdResManagements = rdResManagementMapper.selectList(Wrappers.<RdResManagement>lambdaQuery()
                .eq(RdResManagement::getDeptId, user.getOwnDeptId())).stream().map(RdResManagement::getResId).collect(Collectors.toList());
        if (!rdResManagements.isEmpty()) {
            List<RdResourceDir> list = rdResourceDirService.list(Wrappers.<RdResourceDir>lambdaQuery().in(RdResourceDir::getId, rdResManagements)
                    .notIn(!resIdList.isEmpty(), RdResourceDir::getId, resIdList)
                    .eq(RdResourceDir::getResType, 1));
            for (RdResourceDir dir : list) {
                userResListVos.add(new UserResListVo().setResId(dir.getId()).setResName(dir.getResName()).setState(0));
            }
        }
        // 获取用户还在申请中的资源列表
        List<RdResourceApplicationDetail> list = resOrderService.list(Wrappers.<RdResourceApplicationDetail>lambdaQuery().eq(RdResourceApplicationDetail::getApplyUserId, userId)
                .isNotNull(RdResourceApplicationDetail::getVersionNum).in(RdResourceApplicationDetail::getState, Arrays.asList(2, 3, 4)));
        for (RdResourceApplicationDetail detail : list) {
            userResListVos.add(new UserResListVo().setResId(detail.getResId()).setResName(detail.getResName()).setState(2));
        }
        return userResListVos;
    }

    @Override
    public int isApprovalRes(Integer userId, Integer resId) {
        RdResManagement rdResManagement = rdResManagementMapper.selectOne(Wrappers.<RdResManagement>lambdaQuery().eq(RdResManagement::getUserId, userId).eq(RdResManagement::getResId, resId));
        int approvalState;
        if (null == rdResManagement) {
            // 如果查询不到该记录说明该用户没有此资源权限,进行赋权操作
            approvalState = rdResManagementMapper.insert(new RdResManagement().setCreateTime(new Date()).setUserId(userId).setResId(resId).setSrcDeptName("管理员授权资源"));
        } else {
            // 如果查询到了该记录,说明该用户已经拥有此权限,进行取消授权操作
            approvalState = rdResManagementMapper.delete(Wrappers.<RdResManagement>lambdaQuery().eq(RdResManagement::getUserId, userId).eq(RdResManagement::getResId, resId));
        }
        return approvalState;
    }

    @Override
    public int oneKeyIsApprovalRes(Integer deptId, Integer resId, String userName, Integer type) throws BizException {
        PageQuery pageQuery = new PageQuery();
        long pageSize = 1000;
        pageQuery.setSize(pageSize);
        pageQuery.setCurrent(1);
        PageResult<UserDTO> pageResult = userQueryApi.pageUserInDept(pageQuery, deptId, userName, Boolean.TRUE);
        long pages = pageResult.getPages();
        for (int i = 1; i <= pages; i++) {
            pageQuery.setCurrent(i);
            pageResult = userQueryApi.pageUserInDept(pageQuery, deptId, userName, true);
            List<UserDTO> userList = pageResult.getRecords();
            List<RdResManagement> gsUserRes = rdResManagementMapper.selectList(Wrappers.<RdResManagement>lambdaQuery().in(RdResManagement::getUserId,
                    userList.stream().map(userDTO -> userDTO.getId()).collect(Collectors.toList())).eq(RdResManagement::getResId, resId));
            int userApproveRes = setUserApproveRes(type, resId, userList, gsUserRes);
            if (userApproveRes == 0) {
                log.error("GsUserResServiceImpl(一键授权)-批量授权时出现错误");
                throw new BizException("批量授权时出现错误,请重试");
            } else {
                log.info("为用户批量授权成功");
            }
        }
        return 1;
    }

    private int setUserApproveRes(Integer type, Integer resId, List<UserDTO> userList, List<RdResManagement> gsUserRes) throws BizException {
        List<RdResManagement> needUpdateList = new ArrayList<>();
        int updateState = 0;
        if (type == 0) {
            userList.forEach(userDTO -> {
                // 如果查询不到资源列表说明该部门没有拥有该资源的用户
                if (gsUserRes.size() == 0) {
                    Date now = new Date();
                    RdResManagement res = new RdResManagement().setUserId(userDTO.getId()).setResId(resId).setSrcDeptName("机构管理员-应用权限管理-机构管理员一键授权资源").setCreateTime(now).setUpdateTime(now);
                    needUpdateList.add(res);
                } else {
                    // 查找出没有拥有资源的用户
                    gsUserRes.forEach(userRes -> {
                        if (!userDTO.getId().equals(userRes.getUserId())) {
                            Date now = new Date();
                            RdResManagement res = new RdResManagement().setUserId(userDTO.getId()).setResId(resId).setSrcDeptName("机构管理员-应用权限管理-机构管理员一键授权资源").setCreateTime(now).setUpdateTime(now);
                            needUpdateList.add(res);
                        }
                    });
                }

            });
            Assert.isTrue(needUpdateList.size() == 0, "该部门下的所有用户已经拥有该资源权限");
            // 批量插入没有拥有该资源的用户
            updateState = rdResManagementMapper.batchInsert(needUpdateList);
            log.info("批量插入没有资源的用户:" + needUpdateList.size() + "条");
        }
        if (type == 1) {
            // 查找出拥有资源的用户
            userList.forEach(userDTO -> {
                gsUserRes.forEach(userRes -> {
                    if (userDTO.getId().equals(userRes.getUserId())) {
                        RdResManagement res = new RdResManagement().setId(userRes.getId());
                        needUpdateList.add(res);
                    }
                });
            });
            Assert.isTrue(needUpdateList.size() == 0, "该部门下已经没有用户拥有该资源");
            // 批量删除已经拥有权限的用户
            updateState = rdResManagementMapper.delete(Wrappers.<RdResManagement>lambdaQuery()
                    .in(RdResManagement::getId, needUpdateList.stream().map(userRes -> userRes.getId()).collect(Collectors.toList())));
            log.info("批量删除已经拥有权限的用户:" + needUpdateList.size() + "条");
        }
        return updateState;
    }
}
